// ==UserScript==
// @name         GitHub 
// @description   GitHub Ĳֲ˵ݡ
// @copyright    2016, ¥ (http://www.52cik.com/)
// @icon         https://assets-cdn.github.com/pinned-octocat.svg
// @version      1.6.4
// @author       ¥
// @license      MIT
// @homepageURL  https://github.com/52cik/github-hans
// @match        http://*.github.com/*
// @match        https://*.github.com/*
// @require      https://52cik.github.io/github-hans/locals.js?v1.6.3
// @run-at       document-end
// @grant        none
// ==/UserScript==

(function (window, document, undefined) {
    'use strict';

    var lang = 'zh'; // 

    // 2016-04-18 github  jquery  amd أ¶ȫˡ
    // var $ = require('github/jquery')['default'];

    // Ҫҳ
    var page = getPage();

    transTitle(); // ҳⷭ
    timeElement(); // ʱڵ㷭
    // setTimeout(contributions, 100); //  (Ƕajax, Իڻص¼)
    walk(document.body); // ҳ

    // 2017-03-19 github  require Ϊ Promise ʽ ghImport
    define('github-hans-ajax', ['./jquery'], function($) {
        $(document).ajaxComplete(function () {
            transTitle();
            walk(document.body); // ajax ٴηҳ
        });
    });
    ghImport('github-hans-ajax')['catch'](function(e) {
        setTimeout(function() { throw e });
    });

    /**
     * ڵ
     *
     * @param {Element} node ڵ
     */
    function walk(node) {
        var nodes = node.childNodes;

        for (var i = 0, len = nodes.length; i < len; i++) {
            var el = nodes[i];
            // todo 1. ޸Է; 2. ¼, ԤϢ;

            if (el.nodeType === Node.ELEMENT_NODE) { // Ԫؽڵ㴦

                // ԪؽڵԷ
                if (el.tagName === 'INPUT' || el.tagName === 'TEXTAREA') { //  ť ı
                    if (el.type === 'button' || el.type === 'submit') {
                        transElement(el, 'value');
                    } else {
                        transElement(el, 'placeholder');
                    }
                } else if (el.hasAttribute('aria-label')) { // ʾԪأ tooltip Ч
                    transElement(el, 'aria-label', true);

                    if (el.hasAttribute('data-copied-hint')) { // Ƴɹʾ
                        transElement(el.dataset, 'copiedHint');
                    }
                } else if (el.tagName === 'OPTGROUP') { //  <optgroup>  label 
                    transElement(el, 'label');
                }

                if (el.hasAttribute('data-disable-with')) { // ťȴʾ
                    transElement(el.dataset, 'disableWith');
                }

                //  readme, ļб, ʾ
                if (el.id !== 'readme' && !I18N.conf.reIgnore.test(el.className)) {
                    walk(el); // ӽڵ
                }
            } else if (el.nodeType === Node.TEXT_NODE) { // ıڵ㷭
                transElement(el, 'data');
            }

        }
    }

    /**
     * ȡҳ
     */
    function getPage() {
        // ƥ body  class
        var page = document.body.className.match(I18N.conf.rePageClass);

        if (!page) { // չ url ƥ
            page = location.href.match(I18N.conf.rePageUrl);
        }

        if (!page) { // չ pathname ƥ
            page = location.pathname.match(I18N.conf.rePagePath);
        }

        return page ? page[1] || 'homepage' : false; // ȡҳ key
    }

    /**
     * ҳ
     */
    function transTitle() {
        var title = translate(document.title, 'title');

        if (title === false) { // ޷˳
            return false;
        }

        document.title = title;
    }


    /**
     * ڵӦ
     *
     * @param {object} el 
     * @param {string} field ֶ
     * @param {boolean} isAttr Ƿ attr 
     *
     * @returns {boolean}
     */
    function transElement(el, field, isAttr) {
        var transText = false; // ı

        if (isAttr === undefined) { // Է
            transText = translate(el[field], page);
        } else {
            transText = translate(el.getAttribute(field), page);
        }

        if (transText === false) { // ޷˳
            return false;
        }

        // 滻
        if (isAttr === undefined) {
            el[field] = transText;
        } else {
            el.setAttribute(field, transText);
        }
    }


    /**
     * ı
     *
     * @param {string} text ַ
     * @param {string} page ҳֶ
     *
     * @returns {string|boolean}
     */
    function translate(text, page) { // 
        var str;
        var _key = text.trim(); // ȥβո key
        var _key_neat = _key
            .replace(/\xa0/g, ' ') // 滻 &nbsp; ոµ bug
            .replace(/\s{2,}/g, ' '); // ȥ໻пոַ(Խ׶Σٻָ)

        if (_key_neat === '') {
            return false;
        } // Ϊղ

        str = transPage('pubilc', _key_neat); // 

        if (str !== false && str !== _key_neat) { // 
            str = transPage('pubilc', str) || str;  // ι루Ϊֲ򲿷ַ
            return text.replace(_key, str);  // 滻ԭַհײ
        }

        if (page === false) {
            return false;
        } // δ֪ҳ治

        str = transPage(page, _key_neat); // ֪ҳ
        if (str === false || str === '') {
            return false;
        } // δ֪ݲ

        str = transPage('pubilc', str) || str; // ι루Ϊֲ򲿷ַ
        return text.replace(_key, str); // 滻ԭַհײ
    }


    /**
     * ҳ
     *
     * @param {string} page ҳ
     * @param {string} key 
     *
     * @returns {string|boolean}
     */
    function transPage(page, key) {
        var str; // 
        var res; // 

        // ̬
        str = I18N[lang][page]['static'][key];
        if (str) {
            return str;
        }

        // 
        res = I18N[lang][page].regexp;
        if (res) {
            for (var i = 0, len = res.length; i < len; i++) {
                str = key.replace(res[i][0], res[i][1]);
                if (str !== key) {
                    return str;
                }
            }
        }

        return false; // ûзĿ
    }


    /**
     * ʱڵ㷭
     */
    function timeElement() {
        if (!window.RelativeTimeElement) { // ֹ
            return;
        }

        var RelativeTimeElement$getFormattedDate = RelativeTimeElement.prototype.getFormattedDate;
        var TimeAgoElement$getFormattedDate = TimeAgoElement.prototype.getFormattedDate;
        // var LocalTimeElement$getFormattedDate = LocalTimeElement.prototype.getFormattedDate;

        var RelativeTime = function (str, el) { // ʱ
            if (/^on ([\w ]+)$/.test(str)) {
                return ' ' + el.title.replace(/ .+$/, '');
            }

            // ʹֵ乫ĵڶʱ
            var time_ago = I18N[lang].pubilc.regexp[1];
            return str.replace(time_ago[0], time_ago[1]);
        };

        RelativeTimeElement.prototype.getFormattedDate = function () {
            var str = RelativeTimeElement$getFormattedDate.call(this);
            return RelativeTime(str, this);
        };

        TimeAgoElement.prototype.getFormattedDate = function () {
            var str = TimeAgoElement$getFormattedDate.call(this);
            return RelativeTime(str, this);
        };

        LocalTimeElement.prototype.getFormattedDate = function () {
            return this.title.replace(/ .+$/, '');
        };

        //  time Ԫؽз
        // 2016-04-16 github İ棬 time ǩˡ
        var times = document.querySelectorAll('time, relative-time, time-ago, local-time');
        Array.prototype.forEach.call(times, function (el) {
            if (el.getFormattedDate) { // δע time Ԫ
                el.textContent = el.getFormattedDate();
            }
        });
    }


    /**
     *  ¼
     */
    function contributions() {
        var tip = document.getElementsByClassName('svg-tip-one-line');

        // ȴ IncludeFragmentElement ԪؼϺ¼
        // var observe = require('github/observe').observe;

        define('github/hans-contributions', ['./observe'], function (observe) {
            observe(".js-calendar-graph-svg", function () {
                setTimeout(function () { // ʱ mouseover ¼û
                    var $calendar = $('.js-calendar-graph');
                    walk($calendar[0]); // 

                    $calendar.on('mouseover', '.day', function () {
                        if (tip.length === 0) { // û tip Ԫʱ˳ֹ
                            return true;
                        }

                        var data = $(this).data(); // ȡڵϵ data
                        var $tip = $(tip[0]);

                        $tip.html(data.count + ' ι ' + data.date);

                        var rect = this.getBoundingClientRect(); // ȡԪλ
                        var left = rect.left + window.pageXOffset - tip[0].offsetWidth / 2 + 5.5;

                        $tip.css('left', left);
                    });
                }, 999);
            });
        });

        ghImport('github/hans-contributions')['catch'](function(e) {
            setTimeout(function() { throw e });
        });
    }

})(window, document);
